{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf420
{\fonttbl\f0\fswiss\fcharset77 Arial-BoldMT;\f1\froman\fcharset77 Times-Roman;\f2\fswiss\fcharset77 ArialMT;
\f3\froman\fcharset77 Times-Italic;\f4\fswiss\fcharset77 Arial-BoldItalicMT;\f5\fmodern\fcharset77 Courier;
\f6\ftech\fcharset2 Symbol;}
{\colortbl;\red255\green255\blue255;}
\vieww14200\viewh16480\viewkind0
\deftab720
\pard\pardeftab720\sa120\ql\qnatural

\f0\b\fs48 \cf0 Arrow\

\f1\b0\fs24 Arrow is an inner-process messaging library. The design is in-line with the concept of basic method invocations. It is not designed to represent the standard Supplier/Consumer and Command Patterns. An object has zero knowledge of the types of objects making invocations on its methods. Similarly, an Arrow consumer need never know about the suppliers or even that it is participating in the Arrow messaging system. In other words, any existing C++ object, without modification, can become a consumer of Arrow messages.
\f2 \

\f1 A message instance represents a method call on a set of consumers. Messages are produced by any number of suppliers in any number of threads and are then distributed to any number of consumers. The default message distribution service is provided by a class called the 
\f3\i Channel
\f1\i0 . The channel is easily replaced with alternative implementations but the rest of this document will assume you will use the default channel.\
\pard\pardeftab720\sb240\sa120\ql\qnatural

\f0\b\fs32 \cf0 Motivation
\fs48 \
\pard\pardeftab720\sa120\ql\qnatural

\f1\b0\fs24 \cf0 Arrow was developed to satisfy the requirement of multiple suppliers, executing in separate threads, sending variable types of data to variable lists of consumers, based on some kind of subscription tag. It had to be fast. As requirements further were refined design considerations, such as full consumer decoupling and exception observing were implemented. Features such as message aggregation, threading models, and statistics found their way in as well. \
Arrow is intentionally designed where the message objects know nothing of the components that pass them about. This allows the individual components to be easily replaced without forcing a redesign  of the messages and its associated objects.\
\pard\pardeftab720\sb240\sa120\ql\qnatural

\f0\b\fs32 \cf0 Roles
\f2\b0\fs24 \
\pard\pardeftab720\sb240\sa120\ql\qnatural

\f4\i\b \cf0 Consumers\
\pard\pardeftab720\sa120\ql\qnatural

\f1\i0\b0 \cf0 As detailed in the introduction, the consumer side of the channel is totally open. The consumers do not adhere to an Arrow interface nor do they suffer object-envy with regard to Arrow messages. The messages then need explicit knowledge of the specific type of consumers they may act upon. A message class must detail the single consumer class or interface type that it invokes at distribution.
\f2 \

\f1 A consumer is entered into the channel via the creation of a 
\f3\i Subscription. 
\f1\i0 The subscription links the consumer with a certain breed of message. A consumer may participate in more than one subscription and multiple consumers can share similar subscriptions. 
\f2 \

\f1 NOTE: The channel and subscriptions do not participate in the life cycle management of the consumer. It is the burden of the developer to guarantee that associated subscriptions are destroyed before the consumer enters its destruction process.
\f2 \
\pard\pardeftab720\sb240\sa120\ql\qnatural

\f4\i\b \cf0 Suppliers\
\pard\pardeftab720\sa120\ql\qnatural

\f1\i0\b0 \cf0 Any object or thread of execution that pushes a message into the channel is considered a supplier. They too do not need to adhere to any interface.
\f2 \

\f1 The channel can maintain a collection of special suppliers that adhere to the 
\f3\i IPublisher 
\f1\i0 interface. Publishers are informed of various channel events and state changes so it can react accordingly. They are informed when the channel starts, stops, is destroyed, and has subscriptions made. The rest of this document will assume all suppliers are full-fledged publishers.
\f2 \
\pard\pardeftab720\sb240\sa120\ql\qnatural

\f4\i\b \cf0 Messages\
\pard\pardeftab720\sa120\ql\qnatural

\f1\i0\b0 \cf0 A message is not just cargo or a command being passively delivered to consumers. Upon distribution, it makes explicit invocations on the consumers specifically subscribed to that message. It will likely use member data as parameters for the invocation on the consumer.
\f2 \

\f1 Messages are intended to be subclassed. Subclasses not only provide the behavior of consumer invocation but supply numerous policies for handling within the channel.
\f2 \

\f1 Instantiating a message is a several step task. Publishers must, at least once, register each message type that it will create. This registration process will return a reusable reference to a 
\f3\i Publication 
\f1\i0 object.
\f2  
\f1 The publisher would then request the publication for a 
\f3\i Topic
\f1\i0 . A topic contains both the meta-data the library requires to issue a message and various keys for distributing the message. The topic is required for message construction. Once a message is constructed, it can be issued into the channel. A topic instance is reusable as well.
\f2 \
\pard\tx8010\pardeftab720\sb240\sa120\ql\qnatural

\f4\i\b \cf0 Topics\
\pard\pardeftab720\sa120\ql\qnatural

\f1\i0\b0 \cf0 Topics are routing tags for messages. The are comprised of two keys, publication string, and an arbitrary topic string. Conceptually the  publication string is the message type and the topic string is a subscription distribution list identifier.
\f2 \
\pard\pardeftab720\sb240\sa120\ql\qnatural

\f4\i\b \cf0 Example\
\pard\pardeftab720\ql\qnatural

\f5\i0\b0\fs20 \cf0 	// Create channel\
	Infra::Messaging::Channel channel;
\fs24 \

\fs20 	channel.start();
\fs24 \

\fs20 	// Register Message using < MyMessage > as the publication key
\fs24 \

\fs20 	Infra::Messaging::Publication& pub = channel.publish< MyMessage >();
\fs24 \

\fs20 	// Create consumer and a type safe subscription\
	MyConsumer consumer;\
	Infra::Messaging::Subscription sub = 
\fs24 \

\fs20 		channel.makeTypedSubscription< MyMessage >( &consumer, "MyTopic" );
\fs24 \

\fs20 	// Activation is required to enter the consumer into the dispatch tables.\
	sub.activate();
\fs24 \

\fs20 	// Create message and send it off\
	MyMessage msg( pub.getTopic< MyMessage >( "MyTopic" ) );
\fs24 \

\fs20 	channel.onMessage( msg );
\fs24 \

\fs20 	// Messages may be appropriated derived to support sync calls.\
	msg.wait();\
	\
	// NOTE: all cases of < MyMessage > may be replaced with an arbitrary
\fs24 \

\fs20 	// string. This further decoupling is achieved at the price of losing type\
	// safety.\
\
\pard\pardeftab720\sb240\sa120\ql\qnatural

\f0\b\fs32 \cf0 The Channel\
\pard\pardeftab720\sa120\ql\qnatural

\f1\b0\fs24 \cf0 The channel is the glue that ties all components of the system together. Its components adhere to specific interfaces so new channels may be easily written to satisfy specific needs. Using the interfaces the components are wired up as follows.
\f2 \
\pard\pardeftab720\li720\sa120\ql\qnatural

\f6 \cf0 	
\f1 All Publishers send messages to a queue or message holder
\f2 \

\f6 	
\f1 The message holder sends messages to the queue
\f2 \

\f6 	
\f1 The queue sends messages to the dispatcher
\f2 \

\f6 	
\f1 And the dispatcher invokes the messages with the appropriate consumers
\f2 \
\pard\tx8010\pardeftab720\sb240\sa120\ql\qnatural

\f4\i\b \cf0 The Queue\
\pard\pardeftab720\sa120\ql\qnatural

\f1\i0\b0 \cf0 Messages move straight from the various threads of the publishers into the queue. The queue is a series of prioritized linked lists. As messages come in, their priority is examined and pushed to the end of the appropriate list, assuming the list's maximum size has not been reached.
\f2 \

\f1 A message has the ability to cut-in-line. If an existing message with the same topic exists anywhere in the queue, the new message may be consumed by the existing, enqueued, or dropped, all determined by the existing message. This provides possible live updates of messages that are still enqueued.
\f2 \

\f1 The queue owns a dequeuing policy that can be supplied by the developer. This policy determines the exact next message that gets pulled off the queue. The default is to always pop front of the highest available priority.
\f2 \
\pard\tx8010\pardeftab720\sb240\sa120\ql\qnatural

\f4\i\b \cf0 The Dispatcher\
\pard\pardeftab720\sa120\ql\qnatural

\f1\i0\b0 \cf0 A single thread moves messages from the queue to the dispatcher. Upon entering the dispatcher, the message is invoked in one of several ways.
\f2 \

\f1 Messages have three methods called for consumer invocation , beginDispatching(count), dispatch(consumer), and endDispatch. Messages can supply policy decisions to perform the dispatching from a thread pool. The message can block each consumer invocation, block until all threaded consumer invocations are made, or simply not block at all. The default behavior is to block each consumer invocation. 
\f2 \

\f1 Although blocking may not be optimal, it essentially serializes the threaded invocations of the suppliers onto the consumers. This has the benefit that not only does the consumers need not known anything about the messaging system, they need not be thread-aware, despite the possible multiple threads of the suppliers. The Dispatcher will, in the future, support thread affinity so a consumer need not be thread-aware but can be non-blocking.
\f2 \
\pard\pardeftab720\ql\qnatural

\f1 \cf0 Not all messages that come through have subscriptions associated with them. These special messages have an execute method that is invoked. These messages are normally created if they can know their consumer at construction (eliminates subscription lookup) and a specific threading model is desired. A common use would be the construction of new consumers (where the consumer's constructor is essentially the method invocation).
\f2 \
\pard\tx8010\pardeftab720\sb240\sa120\ql\qnatural

\f4\i\b \cf0 Memory\
\pard\pardeftab720\sa120\ql\qnatural

\f1\i0\b0 \cf0 Messages are heap copied every time they cross thread boundaries. Allocation (particularly deallocation) is expensive. The queue will attempt to reuse the memory of messages passed off to the dispatcher. Messages also support std allocators for further optimizations of message allocations and deallocations.
\f2 \
\pard\pardeftab720\ql\qnatural

\f1 \cf0 Since a message instance constructor and destructor do not represent the beginning and end of the conceptual message moving through the channel, a message is always informed when its passage is being dropped or completed. There are many reasons why a message may be dropped by the channel before any or all of its consumers have been invoked, most notable is an exception. All messages are given the opportunity to clean up their resources when they are dropped by the invocation of its dropped(reason) method.
\f2 \
\pard\tx8010\pardeftab720\sb240\sa120\ql\qnatural

\f4\i\b \cf0 Exception Observing\
\pard\pardeftab720\ql\qnatural

\f1\i0\b0 \cf0 The channel is a method-invocation runtime engine. As such, it needs to be kept running despite an exception thrown from an invocation into the application domain. All application thrown exceptions are caught and passed into a developer supplied exception observer. The application domain observer can then act accordingly. The default behavior is to rethrow the exception that may in-fact shut the messaging system down.
\f2 \
\pard\pardeftab720\sb240\sa120\ql\qnatural

\f0\b\fs32 \cf0 Other Players
\f4\i\fs24 \
\pard\pardeftab720\ql\qnatural

\f1\i0\b0 \cf0 The following are other notable classes and interfaces used within the channel.
\f0\b\fs32 \
\pard\pardeftab720\sb240\sa120\ql\qnatural

\f4\i\fs24 \cf0 IRouter\
\pard\pardeftab720\sa120\ql\qnatural

\f1\i0\b0 \cf0 Any object that receives a message (not the same as consumer invocation) may adhere to the IRouter interface. IRouters are usually used in association with IPublishers. The queue adheres to this interface.
\f2 \
\pard\pardeftab720\sb240\sa120\ql\qnatural

\f4\i\b \cf0 IDispatcher\
\pard\pardeftab720\sa120\ql\qnatural

\f1\i0\b0 \cf0 This interface accepts requests for a consumer to be invoked upon for messages of specific topics and returns subscriptions. It extends the IRouter interface. The channel and dispatcher adhere to this interface. 
\f2 \
\pard\pardeftab720\sb240\sa120\ql\qnatural

\f4\i\b \cf0 MessageHolder\
\pard\pardeftab720\sa120\ql\qnatural

\f1\i0\b0 \cf0 The default behavior for a message sent to the channel that has no consumers subscribed to it, is to be dropped. The MessageHolder is an optional component of the channel that will hold messages until consumers are subscribed to them.  Since it both accepts and reissues messages, it is derived from both IRouter and IPublisher.
\f2 \
\pard\pardeftab720\sb240\sa120\ql\qnatural

\f4\i\b \cf0 Publication Manager\
\pard\pardeftab720\sa120\ql\qnatural

\f1\i0\b0 \cf0 The default channel has a single Publication Manager. The Publication Manager maintains and owns all publications and topics created as message types and subscriptions are registered.
\f2 \
\pard\pardeftab720\sb240\sa120\ql\qnatural

\f4\i\b \cf0 MsgProxy\
\pard\pardeftab720\sa120\ql\qnatural

\f1\i0\b0 \cf0 This class is used to hide the dirty work of exception observing, consumer pointer casting, and meta-data collection. You would only use instances of this class if you were implementing a new channel service. It may be referenced from an associated topic.
\f2 \
\pard\pardeftab720\sb240\sa120\ql\qnatural

\f0\b\fs32 \cf0 Additional Classes
\f4\i\fs24 \
\pard\pardeftab720\ql\qnatural

\f1\i0\b0 \cf0 The library supplies some optional classes.
\f0\b\fs32 \
\pard\pardeftab720\sb240\sa120\ql\qnatural

\f4\i\fs24 \cf0 SynchronousMsg\
\pard\pardeftab720\sa120\ql\qnatural

\f1\i0\b0 \cf0 Any message derived from SynchronouseMsg has an additional interface where the publisher can wait until the message has been fully distributed or dropped. 
\f2 \
\pard\pardeftab720\sb240\sa120\ql\qnatural

\f4\i\b \cf0 RouterMsg\
\pard\pardeftab720\sa120\ql\qnatural

\f1\i0\b0 \cf0 If desired, to invert the message consumer relation to where the message becomes a passive cargo of data, derive your consumers from IRouter and your messages from RouterMsg. RouterMsg simply passes itself into the consumer's IRouter::onMessage method.
\f2 \
\pard\pardeftab720\sb240\sa120\ql\qnatural

\f4\i\b \cf0 TimerFeed\
\pard\pardeftab720\sa120\ql\qnatural

\f1\i0\b0 \cf0 The TimerFeed is a publisher that will not issue a message until a specified time has passed. Since it both accepts and reissues messages, it is derived from both IRouter and IPublisher.
\f2 \
\pard\pardeftab720\sb240\sa120\ql\qnatural

\f4\i\b \cf0 NULLDispatcher\
\pard\pardeftab720\sa120\ql\qnatural

\f1\i0\b0 \cf0 This is a concrete subclass of IDispatcher that creates valid subscriptions but does not make any message invocations. Use this for supplier or queue testing.
\f2 \
\pard\pardeftab720\ql\qnatural

\fs20 \cf0 \
}